package com.demo.security.ssl;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.KeyStore;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManagerFactory;

/**
 * SSL通信客户端
 *
 * @author lee9213@163.com
 * @version 1.0
 * @date 2017/3/17 17:40
 */
public class Client {

    private static SSLSocket sslSocket;

    /**
     * 初始化SSLSocket连接
     * @throws Exception
     */
    public static void init() throws Exception {
        String host = "127.0.0.1";
        int port = 1234;

        //包含客户端的私钥与服务端的证书
        String keyStorePath = "/home/temp/ssl/client.keystore";
        String trustKeyStroePath = "/home/temp/ssl/ca-trust.keystore";
        String keyStorePassword = "123456";

        SSLContext sslContext = SSLContext.getInstance("SSL");

        //密钥库
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("sunx509");

        //信任库
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("sunx509");

        KeyStore keyStore = KeyStore.getInstance("pkcs12");
        KeyStore trustKeyStore = KeyStore.getInstance("jks");

        FileInputStream keyStoreFis = new FileInputStream(keyStorePath);
        keyStore.load(keyStoreFis,keyStorePassword.toCharArray());

        FileInputStream trustKeyStoreFis = new FileInputStream(trustKeyStroePath);
        trustKeyStore.load(trustKeyStoreFis,keyStorePassword.toCharArray());

        keyManagerFactory.init(keyStore,keyStorePassword.toCharArray());
        trustManagerFactory.init(trustKeyStore);

        //上下文初始化
        sslContext.init(keyManagerFactory.getKeyManagers(),trustManagerFactory.getTrustManagers(),null);

        //SSLSocket初始化
        sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket(host,port);

    }

    /**
     * 进行SSL通信
     * @throws Exception
     */
    public static void process() throws Exception {
        String hello = "hello";
        OutputStream outputStream = sslSocket.getOutputStream();
        outputStream.write(hello.getBytes(),0,hello.getBytes().length);
        outputStream.flush();

        byte[] inputBytes = new byte[20];
        InputStream inputStream = sslSocket.getInputStream();
        inputStream.read(inputBytes);

        System.out.println(new String(inputBytes));
    }
}
